#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @time: 2024/5/15 17:53
# @Author : Admin
from typing import Sequence

import pyzentao

from Utils.TestCase import TestCase
from framework.utils.log_record_util import get_logger
logger = get_logger()


# 'products': {
#     '21': 'YZ07B',
#     '20': 'Z7',
#     '19': 'Z6',
#     '18': 'N1',
#     '17': 'Q50A',
#     '16': 'YZ07',
#     '15': 'Q50',
#     '13': 'YS200',
#     '12': 'YZ30',
#     '11': 'YZ21',
#     '9': '物料导入',
#     '8': 'YZ06',
#     '7': 'Tools',
#     '6': 'System',
#     '5': 'CS21L',
#     '4': 'YZ05',
#     '3': 'CS11',
#     '2': 'YZ61',
#     '1': 'CS21'
# }


class zentaoTools():
    zentao = None
    Logger = None
    product = None
    products_dict = {
        'Z7': '20',
        'Z6': '19',
        'N1': '18',
        'Q50A': '17',
        'YZ07': '16',
        'Q50': '15',
        'YS200': '13',
        'YZ30': '12',
        'YZ21': '11',
        'YZ06': '8',
        'M61': '26',
    }

    # productID = caseLib_id

    moudle_id_dict = None
    moudle_id_dict_caselib = {"PosTerminal": '220',
                              "CardReaderDevice": '221',
                              "EMVDevice": '222',
                              "PinPadDevice": '223',
                              "PrinterDevice": '224',
                              "ScannerDevice": '225',
                              "PowerManagerDevice": '263',
                              "NetTest": '266',
                              "IntergratedTest": '274',
                              "USB": '276',
                              "电源相关": '278',
                              "NetTest2": '292',
                              "StorageTest": '47'}

    moudle_id_dict_product = {"PosTerminal": '227',
                              "CardReaderDevice": '228',
                              "EMVDevice": '229',
                              "PinPadDevice": '230',
                              "PrinterDevice": '231',
                              "ScannerDevice": '232',
                              "PMDevice": '260',
                              "NetTest": '261',
                              "NetTest2": '296',
                              "IntergratedTest": '297',
                              "StorageTest": '281'}

    # sdk_module_id = "226"

    def __init__(self, zentao_name, zentao_passwd, frame=None):
        self.Logger = frame
        self.zentao = pyzentao.Zentao({
            "url": "http://192.168.15.10:13888//zentao",
            "username": zentao_name,
            "password": zentao_passwd,
            "spec": "./Utils/zentao/pyzentao-specs/v15.7"
        })
        result = self.zentao.qa()
        if self.Logger is not None:
            self.Logger.append("" + result.status)
        logger.info("" + result.status)
        pass
    def checkConnection(self):
        self.zentao.reconnect()
        pass
    def setProduct(self, product):
        self.product = product
        self.productID = zentaoTools.products_dict[product.upper()]
        self.caseLib_id = self.productID  # 用例：Z6

    def setIsCaseLib(self, isCaseLib):
        logger.info("setIsCaseLib:" + str(isCaseLib))
        if isCaseLib is True:
            # self.caselib_browse_updateModules()
            self.moudle_id_dict = self.moudle_id_dict_caselib
            if self.product == "Z6":
                self.caseLib_id = 11  # 用例库：安卓软件测试
            elif self.product == "M61":
                self.caseLib_id = 49  # 用例库：RTOS系统软件测试
            else:
                self.caseLib_id = 50  # 用例库：Linux系统软件测试
        else:
            # self.testcase_browse_updateModules()
            self.moudle_id_dict = self.moudle_id_dict_product
            self.caseLib_id = self.productID
    '''
    lib: 11
    module: 220
    type: feature
    stage[]: 
    title: test
    color: 
    pri: 3
    precondition: 
    steps[1]: test1
    stepType[1]: item
    expects[1]: test1111
    steps[2]: test2
    stepType[2]: item
    expects[2]: test222
    steps[3]: test3
    stepType[3]: item
    expects[3]: test333
    keywords: 
    labels[]: 
    files[]: (二进制)
    '''

    def caselib_createCase(self, testcase: TestCase, moudle_name):
        try:
            if len(self.moudle_id_dict) == 0:
                self.caselib_browse_updateModules()
            moduleID = self.moudle_id_dict.get(moudle_name)
            result = self.zentao.caselib_createCase(
                libID=self.caseLib_id,
                moduleID=self.moudle_id_dict.get(moudle_name),
                data={
                    "lib": self.caseLib_id,
                    "module": self.moudle_id_dict.get(moudle_name),
                    "type": "feature",
                    "precondition": testcase.TCPrecondition,
                    "title": testcase.TCName + ":" + testcase.TCSummary,
                    "steps[1]": testcase.TCAction,
                    "stepType[1]": "item",
                    "expects[1]": testcase.TCResult
                }
            )
            logger.info(result.status)
            if self.Logger is not None:
                self.Logger.append(result.status)
            logger.info(result.data)
        except Exception as e:
            logger.info(e)
            logger.info("FAIL:caselib_createCase:" + testcase.TCName)
        return

    def testcase_create(self, testcase: TestCase, moudle_name):
        try:
            if len(self.moudle_id_dict) == 0:
                self.testcase_browse_updateModules()

            result = self.zentao.testcase_create(
                branch=self.productID,
                moduleID=self.moudle_id_dict.get(moudle_name),
                # branch=projectID,
                data={
                    "product": self.productID,
                    "module": self.moudle_id_dict.get(moudle_name),
                    "type": "feature",
                    "precondition": testcase.TCPrecondition,
                    "title": testcase.TCName + ":" + testcase.TCSummary,
                    "steps[1]": testcase.TCAction,
                    "stepType[1]": "item",
                    "expects[1]": testcase.TCResult
                }
                #  - branch
                #  - moduleID
                #  - from
                # - param
                # - storyID
                # - extras
            )
            logger.info(result.status)
            if self.Logger is not None:
                self.Logger.append(result.status)
            logger.info(result.data)
        except Exception as e:
            logger.info(e)
            logger.info("FAIL:caselib_createCase:" + testcase.TCName)
        return

    def testcase_edit(self, caseID, testcase, isLib=True):
        if isLib:
            result = self.zentao.testcase_edit(
                caseID=caseID,
                data={
                    "lib": self.caseLib_id,
                    "type": "feature",
                    "precondition": testcase.TCPrecondition,
                    "title": testcase.TCName + ":" + testcase.TCSummary,
                    "steps[1]": testcase.TCAction,
                    "stepType[1]": "item",
                    "expects[1]": testcase.TCResult
                }
            )
        else:
            result = self.zentao.testcase_edit(
                caseID=caseID,
                data={
                    "product": self.productID,
                    "type": "feature",
                    "precondition": testcase.TCPrecondition,
                    "title": testcase.TCName + ":" + testcase.TCSummary,
                    "steps[1]": testcase.TCAction,
                    "stepType[1]": "item",
                    "expects[1]": testcase.TCResult
                }
            )
        logger.info(result.status)
        if self.Logger is not None:
            self.Logger.append(result.status)
        logger.info(result.data)

    def testcase_view(self, caseID):
        result = self.zentao.testcase_edit(
            caseID=caseID,
        )
        # logger.info(result.status)
        # logger.info(result.data)

        case_tmp = result.data["case"]
        if ":" in case_tmp["title"]:
            casename, casesummary = case_tmp["title"].split(':')
            casesummary = casesummary.replace("&gt;", ">", 5).replace("&quot;", "\"", 10).replace("amp;", "")
        else:
            casename = case_tmp["title"]
            casesummary = ""

        TCAction = ""
        TCResult = ""
        stepsId = ""
        try:
            for stepsId_tmp, step_tmp in case_tmp["steps"].items():
                TCAction = step_tmp["desc"].replace("&gt;", ">", 5).replace("&quot;", "\"", 10).replace("amp;", "")
                TCResult = step_tmp["expect"].replace("&gt;", ">", 5).replace("&quot;", "\"", 10).replace("amp;", "")
                stepsId = stepsId_tmp
                break
        except Exception as e:
            TCAction = ""
            TCResult = ""
            stepsId = ""

        testcase = TestCase(id=case_tmp["id"], stepsId=stepsId, TCName=casename, TCSummary=casesummary,
                            TCAction=TCAction, TCResult=TCResult)
        # logger.info(testcase)
        return testcase

    def testcase_delete(self, caseIdList):
        for caseId in caseIdList:
            result = self.zentao.testcase_delete(
                caseID=caseId,
                confirm="yes"
            )
            # logger.info(result.status)
            # logger.info(result.data)

    def caselib_browse_updateModules(self):
        # 禅道用例库中的用例获取
        result = self.zentao.caselib_browse(
            libID=self.caseLib_id,
            orderBy="id_desc",
            recTotal=100,
            recPerPage=100,
            pageID=1
        )

        logger.info(result.status)
        logger.info(result.data)
        logger.info("start update moudle_id_dict:caselib_browse")

        self.moudle_id_dict = result.data["modulePairs"]
        logger.info(self.moudle_id_dict)
        pass

    def caselib_browse(self, moudle_name) -> Sequence[TestCase]:
        # 禅道用例库中的用例获取
        if len(self.moudle_id_dict) == 0:
            self.caselib_browse_updateModules()

        moduleId = self.moudle_id_dict.get(moudle_name)
        result = self.zentao.caselib_browse(
            libID=self.caseLib_id,
            orderBy="id_desc",
            browseType="bymodule",
            param=self.moudle_id_dict.get(moudle_name),
            recTotal=100,
            recPerPage=100,
            pageID=1
            # - browseType
            # - param
            # - orderBy
            # - recTotal
            # - recPerPage
            # - pageID

        )

        # logger.info(result.status)
        # logger.info(result.data)

        testcase_dict = {}
        case_dict = result.data["cases"]
        for key, value in result.data["modulePairs"].items():
            self.moudle_id_dict_caselib.update({value:key})

        if moduleId is None:
            moduleId = self.moudle_id_dict.get(moudle_name)
            result = self.zentao.caselib_browse(
                libID=self.caseLib_id,
                orderBy="id_desc",
                browseType="bymodule",
                param=self.moudle_id_dict.get(moudle_name),
                recTotal=100,
                recPerPage=100,
                pageID=1
                # - browseType
                # - param
                # - orderBy
                # - recTotal
                # - recPerPage
                # - pageID
            )
            case_dict = result.data["cases"]

        try:
            for case_tmp in case_dict.values():
                # logger.info("case_tmp id:" + case_tmp["id"])
                testcase = self.testcase_view(case_tmp["id"])
                if ":" in case_tmp["title"]:
                    caseName = case_tmp["title"].split(":")[0]
                else:
                    caseName = case_tmp["title"]
                testcase_dict[caseName] = testcase
        except Exception as e:
            return testcase_dict

        return testcase_dict
        pass
    def testcase_browse_updateModules(self):
        # 禅道用例获取
        result = self.zentao.testcase_browse(
            productID=self.productID + "-",
            orderBy="id_desc",
            recTotal=100,
            recPerPage=100,
            pageID=1,
            projectID=""
        )
        # logger.info(result.status)
        # logger.info(result.data)
        logger.info("start update moudle_id_dict")

        module_dict = result.data["modules"]

        for key, value in module_dict.items():
            self.moudle_id_dict.update({value.replace("/SDK/", "").replace("/", ""): key})
        logger.info(self.moudle_id_dict)

    def testcase_browse(self, moudle_name) -> Sequence[TestCase]:
        if len(self.moudle_id_dict) == 0:
            self.testcase_browse_updateModules()

        moduleid = self.moudle_id_dict.get(moudle_name)
        # 禅道用例获取
        result = self.zentao.testcase_browse(
            productID=self.productID + "-",
            orderBy="id_desc",
            browseType="bymodule",
            param=self.moudle_id_dict.get(moudle_name),
            recTotal=100,
            recPerPage=100,
            pageID=1,
            projectID=""
        )
        #
        # logger.info(result.status)
        # logger.info(result.data)

        testcase_dict = {}
        case_dict = result.data["cases"]

        module_dict = result.data["modules"]
        for key, value in module_dict.items():
            self.moudle_id_dict_product.update({value.replace("/SDK/", "").replace("/SDK_PalmPay/", "").replace("/", ""): key})

        if moduleid is None:
            moduleid = self.moudle_id_dict.get(moudle_name)
            result = self.zentao.testcase_browse(
                productID=self.productID + "-",
                orderBy="id_desc",
                browseType="bymodule",
                param=self.moudle_id_dict.get(moudle_name),
                recTotal=100,
                recPerPage=100,
                pageID=1,
                projectID=""
            )
            case_dict = result.data["cases"]

        try:
            for case_tmp in case_dict.values():
                # logger.info("case_tmp id:" + case_tmp["id"])
                testcase = self.testcase_view(case_tmp["id"])
                if ":" in case_tmp["title"]:
                    caseName = case_tmp["title"].split(":")[0]
                else:
                    caseName = case_tmp["title"]
                testcase_dict[caseName] = testcase
        except Exception as e:
            return testcase_dict
        return testcase_dict

    def testcase_browse_all(self) -> Sequence[TestCase]:
        # 禅道用例获取
        logger.info("productID:" + self.productID)

        result = self.zentao.testcase_browse(
            productID=self.productID + "-",
            orderBy="id_desc",
            browseType="all",
            param="0",
            recTotal=500,
            recPerPage=500,
            pageID=1,
            projectID=""
        )
        #
        # logger.info(result.status)
        # logger.info(result.data)

        testcase_dict = {}
        case_dict = result.data["cases"]
        try:
            for case_tmp in case_dict.values():
                # logger.info("case_tmp id:" + case_tmp["id"])
                testcase = self.testcase_view(case_tmp["id"])
                if ":" in case_tmp["title"]:
                    caseName = case_tmp["title"].split(":")[0]
                else:
                    caseName = case_tmp["title"]
                testcase_dict[caseName] = testcase
        except Exception as e:
            return testcase_dict
        return testcase_dict

    def testtask_runCase(self, runID, stepsId, result, resultFile=None, caseID=None):
        data_tmp = None
        if resultFile != None:
            if len(resultFile) < 60*1024:  # 2  20*1024
                data_tmp = {
                    "steps[" + stepsId + "]": result,
                    "reals[" + stepsId + "]": resultFile,
                }
            else:
                data_tmp = {
                    "steps[" + stepsId + "]": result,
                    "reals[" + stepsId + "]": resultFile[:60*1024-1024] + resultFile[-1024:],
                }
                # tmp_file = "./test_log_" + runID + ".txt"
                # filename= "test_log_" + runID + ".txt"
                # with open(tmp_file, "w+") as f:
                #     f.write(resultFile)
                #     f.flush()
                #
                # with open(tmp_file, "rb") as f:
                #     data_tmp = {
                #         "steps[" + stepsId + "]": result,
                #         "reals[" + stepsId + "]": "",
                #         "case": caseID,
                #         "labels" + stepsId + "[]": filename,
                #         "files" + stepsId + "[]": f.read(),
                #     }
        else:
            data_tmp = {
                "steps[" + stepsId + "]": result,
            }

        result = self.zentao.testtask_runCase(
            runID=runID,
            # extras="caseID=" + 5955 + ,
            data=data_tmp,
        )

        # logger.info(result.status)
        # logger.info(result.data)
        if result.status == "success":
            return True
        return False
        pass

    def testtask_cases(self, taskID):
        # 禅道任务单中的用例获取
        caseRunIdDict = {}
        result = self.zentao.testtask_cases(
            taskID=taskID,
            # orderBy="id_desc",
            browseType="byModule",
            # param=self.sdk_module_id + "-lastRunResult_asc-200-200",
            param="0" + "-lastRunResult_asc-400-400",
            # recTotal=100,
            # recPerPage=100,
            # pageID=1

        )

        # logger.info(result.status)
        # logger.info(result.data)
        tmp_runID_dict = result.data["runs"]
        for case_tmp in tmp_runID_dict.values():
            caseName = ""
            if ":" in case_tmp["title"]:
                caseName = case_tmp["title"].split(":")[0]
            else:
                caseName = case_tmp["title"]
            caseRunIdDict[caseName] = case_tmp["id"]
        return caseRunIdDict
        pass
